using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Runtime.Serialization.Formatters.Binary;
using TMPro;
using UnityEngine;
using UnityEngine.EventSystems;
using UnityEngine.UI;
using Object = UnityEngine.Object;

namespace EntityKit.Runtime
{
    /// <summary>
    /// 物体可见性状态枚举
    /// </summary>
    public enum VisibilityState
    {
        /// <summary>
        /// 不可见
        /// </summary>
        NotVisible,
        
        /// <summary>
        /// 部分可见
        /// </summary>
        PartiallyVisible,
        
        /// <summary>
        /// 完全可见
        /// </summary>
        FullyVisible
    }

    public static class UnityHelper
    {
        
        #region Transform相关扩展

        /// <summary>
        /// 激活/禁用所有子对象
        /// </summary>
        public static void SetActiveAllChildren(this GameObject parent, bool active)
        {
            foreach (Transform child in parent.transform)
            {
                child.gameObject.SetActive(active);
            }
        }

        /// <summary>
        /// 激活/禁用所有子对象
        /// </summary>
        public static void SetActiveAllChildren(this Transform parent, bool active)
        {
            foreach (Transform child in parent)
            {
                child.gameObject.SetActive(active);
            }
        }

        /// <summary>
        /// 激活/禁用所有子对象
        /// </summary>
        public static void SetActiveAllChildren(this Component parent, bool active)
        {
            foreach (Transform child in parent.transform)
            {
                child.gameObject.SetActive(active);
            }
        }

        /// <summary>
        /// 重置变换组件到默认状态
        /// </summary>
        public static void Reset(this Transform transform)
        {
            transform.localPosition = Vector3.zero;
            transform.localRotation = Quaternion.identity;
            transform.localScale = Vector3.one;
        }

        /// <summary>
        /// 设置Transform的x坐标
        /// </summary>
        public static void SetX(this Transform transform, float x)
        {
            Vector3 newPosition = new Vector3(x, transform.position.y, transform.position.z);
            transform.position = newPosition;
        }

        /// <summary>
        /// 设置Transform的y坐标
        /// </summary>
        public static void SetY(this Transform transform, float y)
        {
            Vector3 newPosition = new Vector3(transform.position.x, y, transform.position.z);
            transform.position = newPosition;
        }

        /// <summary>
        /// 设置Transform的z坐标
        /// </summary>
        public static void SetZ(this Transform transform, float z)
        {
            Vector3 newPosition = new Vector3(transform.position.x, transform.position.y, z);
            transform.position = newPosition;
        }

        /// <summary>
        /// 设置Transform的局部x坐标
        /// </summary>
        public static void SetLocalX(this Transform transform, float x)
        {
            Vector3 newPosition = new Vector3(x, transform.localPosition.y, transform.localPosition.z);
            transform.localPosition = newPosition;
        }

        /// <summary>
        /// 设置Transform的局部y坐标
        /// </summary>
        public static void SetLocalY(this Transform transform, float y)
        {
            Vector3 newPosition = new Vector3(transform.localPosition.x, y, transform.localPosition.z);
            transform.localPosition = newPosition;
        }

        /// <summary>
        /// 设置Transform的局部z坐标
        /// </summary>
        public static void SetLocalZ(this Transform transform, float z)
        {
            Vector3 newPosition = new Vector3(transform.localPosition.x, transform.localPosition.y, z);
            transform.localPosition = newPosition;
        }

        /// <summary>
        /// 在世界坐标系中平移对象
        /// </summary>
        public static void TranslateX(this Transform transform, float x)
        {
            Vector3 newPosition = new Vector3(transform.position.x + x, transform.position.y, transform.position.z);
            transform.position = newPosition;
        }

        /// <summary>
        /// 在世界坐标系中平移对象
        /// </summary>
        public static void TranslateY(this Transform transform, float y)
        {
            Vector3 newPosition = new Vector3(transform.position.x, transform.position.y + y, transform.position.z);
            transform.position = newPosition;
        }

        /// <summary>
        /// 在世界坐标系中平移对象
        /// </summary>
        public static void TranslateZ(this Transform transform, float z)
        {
            Vector3 newPosition = new Vector3(transform.position.x, transform.position.y, transform.position.z + z);
            transform.position = newPosition;
        }

        #endregion

        #region 组件获取相关扩展

        /// <summary>
        /// 获取RectTransform组件
        /// </summary>
        public static RectTransform RectTransform(this Transform tran)
        {
            return tran.GetComponent<RectTransform>();
        }

        /// <summary>
        /// 获取RectTransform组件
        /// </summary>
        public static RectTransform RectTransform(this GameObject obj)
        {
            return obj.GetComponent<RectTransform>();
        }

        /// <summary>
        /// 获取RectTransform组件
        /// </summary>
        public static RectTransform RectTransform(this Component component)
        {
            return component.GetComponent<RectTransform>();
        }

        /// <summary>
        /// 获取CanvasGroup组件
        /// </summary>
        /// <param name="obj"></param>
        /// <returns></returns>
        public static CanvasGroup CanvasGroup(this GameObject obj)
        {
            return obj.GetComponent<CanvasGroup>();
        }

        /// <summary>
        /// 获取CanvasGroup组件
        /// </summary>
        public static CanvasGroup CanvasGroup(this Component component)
        {
            return component.GetComponent<CanvasGroup>();
        }

        /// <summary>
        /// 获取CanvasGroup组件
        /// </summary>
        public static CanvasGroup CanvasGroup(this Transform transform)
        {
            return transform.GetComponent<CanvasGroup>();
        }

        /// <summary>
        /// 获取CanvasGroup组件
        /// </summary>
        /// <param name="obj"></param>
        /// <returns></returns>
        public static ToggleGroup ToggleGroup(this GameObject obj)
        {
            return obj.GetComponent<ToggleGroup>();
        }

        /// <summary>
        /// 获取CanvasGroup组件
        /// </summary>
        public static ToggleGroup ToggleGroup(this Component component)
        {
            return component.GetComponent<ToggleGroup>();
        }

        /// <summary>
        /// 获取CanvasGroup组件
        /// </summary>
        public static ToggleGroup ToggleGroup(this Transform transform)
        {
            return transform.GetComponent<ToggleGroup>();
        }

        /// <summary>
        /// 获取或添加组件
        /// </summary>
        public static T GetOrAddComponent<T>(this GameObject gameObject) where T : Component
        {
            T component = gameObject.GetComponent<T>();
            if (component == null)
            {
                component = gameObject.AddComponent<T>();
            }

            return component;
        }

        /// <summary>
        /// 获取或添加组件
        /// </summary>
        public static Component GetOrAddComponent(this GameObject gameObject, Type type)
        {
            Component component = gameObject.GetComponent(type);
            if (component == null)
            {
                component = gameObject.AddComponent(type);
            }

            return component;
        }

        #endregion

        #region 子对象操作相关

        /// <summary>
        /// 获取所有子对象
        /// </summary>
        public static List<Transform> GetAllChildren(this Transform parent)
        {
            List<Transform> children = new List<Transform>();
            foreach (Transform child in parent)
            {
                children.Add(child);
            }

            return children;
        }

        /// <summary>
        /// 获取所有子对象
        /// </summary>
        public static List<T> GetAllChildren<T>(this Transform parent) where T : Component
        {
            List<T> children = new List<T>();
            foreach (Transform child in parent)
            {
                children.Add(child.GetComponent<T>());
            }

            return children;
        }

        /// <summary>
        /// 清空所有子对象
        /// </summary>
        public static void ClearChildren(this Transform parent)
        {
            for (int i = parent.childCount - 1; i >= 0; i--)
            {
                Object.Destroy(parent.GetChild(i).gameObject);
            }
        }

        #endregion

        #region 颜色处理相关

        /// <summary>
        /// 颜色转换为十六进制字符串
        /// </summary>
        public static string ToHex(this Color color)
        {
            return $"#{ColorUtility.ToHtmlStringRGBA(color)}";
        }

        /// <summary>
        /// 从十六进制字符串创建颜色
        /// </summary>
        public static Color FromHex(string hex)
        {
            ColorUtility.TryParseHtmlString(hex, out Color color);
            return color;
        }

        #endregion

        #region 摄像机检测相关

        /// <summary>
        /// 检查世界坐标是否在摄像机视野内
        /// </summary>
        public static bool IsVisible(this Camera camera, Vector3 worldPosition)
        {
            Vector3 viewPos = camera.WorldToViewportPoint(worldPosition);
            return (viewPos.x >= 0 && viewPos.x <= 1 && viewPos.y >= 0 && viewPos.y <= 1 && viewPos.z > 0);
        }

        /// <summary>
        /// 检查整个物体是否在摄像机视野内
        /// </summary>
        public static bool IsVisible(this Camera camera, GameObject gameObject)
        {
            Renderer renderer = gameObject.GetComponent<Renderer>();
            if (renderer == null)
                return false;

            // 获取物体的包围盒
            Bounds bounds = renderer.bounds;
            
            // 使用视锥体平面检测包围盒是否在视锥体内
            return GeometryUtility.TestPlanesAABB(GeometryUtility.CalculateFrustumPlanes(camera), bounds);
        }

        /// <summary>
        /// 检查整个物体是否完全在摄像机视野内
        /// </summary>
        public static bool IsFullyVisible(this Camera camera, GameObject gameObject)
        {
            Renderer renderer = gameObject.GetComponent<Renderer>();
            if (renderer == null)
                return false;

            // 获取物体的包围盒
            Bounds bounds = renderer.bounds;
            
            // 获取包围盒的8个顶点
            Vector3[] corners = new Vector3[8];
            corners[0] = bounds.min;
            corners[1] = bounds.max;
            corners[2] = new Vector3(bounds.min.x, bounds.min.y, bounds.max.z);
            corners[3] = new Vector3(bounds.min.x, bounds.max.y, bounds.min.z);
            corners[4] = new Vector3(bounds.max.x, bounds.min.y, bounds.min.z);
            corners[5] = new Vector3(bounds.min.x, bounds.max.y, bounds.max.z);
            corners[6] = new Vector3(bounds.max.x, bounds.min.y, bounds.max.z);
            corners[7] = new Vector3(bounds.max.x, bounds.max.y, bounds.min.z);

            // 检查所有顶点是否都在视野内
            foreach (Vector3 corner in corners)
            {
                if (!camera.IsVisible(corner))
                    return false;
            }
            
            // 只有当包围盒的所有部分都在视野内，物体才完全可见
            return true;
        }
        
        /// <summary>
        /// 检查物体的可见性状态
        /// </summary>
        /// <returns>VisibilityState枚举: NotVisible(不可见), PartiallyVisible(部分可见), FullyVisible(完全可见)</returns>
        public static VisibilityState GetVisibilityState(this Camera camera, GameObject gameObject)
        {
            Renderer renderer = gameObject.GetComponent<Renderer>();
            if (renderer == null)
                return VisibilityState.NotVisible;

            // 获取物体的包围盒
            Bounds bounds = renderer.bounds;
            
            // 先检查是否完全不可见
            if (!GeometryUtility.TestPlanesAABB(GeometryUtility.CalculateFrustumPlanes(camera), bounds))
                return VisibilityState.NotVisible;
                
            // 检查是否完全可见
            Vector3[] corners = new Vector3[8];
            corners[0] = bounds.min;
            corners[1] = bounds.max;
            corners[2] = new Vector3(bounds.min.x, bounds.min.y, bounds.max.z);
            corners[3] = new Vector3(bounds.min.x, bounds.max.y, bounds.min.z);
            corners[4] = new Vector3(bounds.max.x, bounds.min.y, bounds.min.z);
            corners[5] = new Vector3(bounds.min.x, bounds.max.y, bounds.max.z);
            corners[6] = new Vector3(bounds.max.x, bounds.min.y, bounds.max.z);
            corners[7] = new Vector3(bounds.max.x, bounds.max.y, bounds.min.z);

            bool allCornersVisible = true;
            foreach (Vector3 corner in corners)
            {
                if (!camera.IsVisible(corner))
                {
                    allCornersVisible = false;
                    break;
                }
            }
            
            if (allCornersVisible)
                return VisibilityState.FullyVisible;
            else
                return VisibilityState.PartiallyVisible;
        }

        #endregion

        #region 屏幕边缘交点相关

        /// <summary>
        /// 计算两点连线与屏幕边缘的交点
        /// </summary>
        /// <param name="screenPointA">起始点屏幕坐标</param>
        /// <param name="screenPointB">目标点屏幕坐标</param>
        /// <returns>与屏幕边缘的交点坐标</returns>
        public static Vector3 GetScreenEdgeIntersection(Vector3 screenPointA, Vector3 screenPointB)
        {
            // 屏幕边界
            float screenWidth = Screen.width;
            float screenHeight = Screen.height;
            
            // 定义屏幕的四条边
            // Left edge: x = 0
            Vector2 leftIntersection = GetLineIntersectionPoint(screenPointA, screenPointB, new Vector2(0, 0), new Vector2(0, screenHeight));
            if (leftIntersection != Vector2.zero && leftIntersection.y >= 0 && leftIntersection.y <= screenHeight)
            {
                return leftIntersection;
            }
            
            // Right edge: x = screenWidth
            Vector2 rightIntersection = GetLineIntersectionPoint(screenPointA, screenPointB, new Vector2(screenWidth, 0), new Vector2(screenWidth, screenHeight));
            if (rightIntersection != Vector2.zero && rightIntersection.y >= 0 && rightIntersection.y <= screenHeight)
            {
                return rightIntersection;
            }
            
            // Bottom edge: y = 0
            Vector2 bottomIntersection = GetLineIntersectionPoint(screenPointA, screenPointB, new Vector2(0, 0), new Vector2(screenWidth, 0));
            if (bottomIntersection != Vector2.zero && bottomIntersection.x >= 0 && bottomIntersection.x <= screenWidth)
            {
                return bottomIntersection;
            }
            
            // Top edge: y = screenHeight
            Vector2 topIntersection = GetLineIntersectionPoint(screenPointA, screenPointB, new Vector2(0, screenHeight), new Vector2(screenWidth, screenHeight));
            if (topIntersection != Vector2.zero && topIntersection.x >= 0 && topIntersection.x <= screenWidth)
            {
                return topIntersection;
            }
            
            // 如果没有找到交点，返回点B
            return screenPointB;
        }
        
        /// <summary>
        /// 计算两点连线与屏幕边缘的交点
        /// </summary>
        /// <param name="camera">相机</param>
        /// <param name="worldPointA">起始点世界坐标</param>
        /// <param name="worldPointB">目标点世界坐标</param>
        /// <returns>与屏幕边缘的交点屏幕坐标</returns>
        public static Vector3 GetScreenEdgeIntersection(this Camera camera, Vector3 worldPointA, Vector3 worldPointB)
        {
            // 将世界坐标转换为屏幕坐标
            Vector3 screenPointA = camera.WorldToScreenPoint(worldPointA);
            Vector3 screenPointB = camera.WorldToScreenPoint(worldPointB);
            
            return GetScreenEdgeIntersection(screenPointA, screenPointB);
        }
        
        /// <summary>
        /// 计算线段与线段的交点
        /// </summary>
        public static Vector2 GetLineIntersectionPoint(Vector2 a1, Vector2 a2, Vector2 b1, Vector2 b2)
        {
            Vector2 b = a2 - a1;
            Vector2 d = b2 - b1;
            float bDotDPerp = b.x * d.y - b.y * d.x;
            
            // 检查是否平行
            if (Mathf.Approximately(bDotDPerp, 0))
                return Vector2.zero;
            
            Vector2 c = b1 - a1;
            float t = (c.x * d.y - c.y * d.x) / bDotDPerp;
            float u = (c.x * b.y - c.y * b.x) / bDotDPerp;
            
            // 检查交点是否在两条线段上
            if (t >= 0 && t <= 1 && u >= 0 && u <= 1)
            {
                return a1 + t * b;
            }
            
            return Vector2.zero;
        }
        
        /// <summary>
        /// 检查屏幕坐标点是否在屏幕内
        /// </summary>
        /// <param name="screenPoint">屏幕坐标点</param>
        /// <returns>点是否在屏幕内</returns>
        public static bool IsPointOnScreen(Vector3 screenPoint)
        {
            return screenPoint.x >= 0 && screenPoint.x <= Screen.width && 
                   screenPoint.y >= 0 && screenPoint.y <= Screen.height && 
                   screenPoint.z > 0;
        }

        #endregion

        #region 数组和列表操作相关

        /// <summary>
        /// 打乱数组顺序
        /// </summary>
        public static void Shuffle<T>(this T[] array)
        {
            for (int i = array.Length - 1; i > 0; i--)
            {
                int j = UnityEngine.Random.Range(0, i + 1);
                (array[i], array[j]) = (array[j], array[i]);
            }
        }

        /// <summary>
        /// 打乱列表顺序
        /// </summary>
        public static void Shuffle<T>(this List<T> list)
        {
            for (int i = list.Count - 1; i > 0; i--)
            {
                int j = UnityEngine.Random.Range(0, i + 1);
                (list[i], list[j]) = (list[j], list[i]);
            }
        }

        /// <summary>
        /// 获取不重复随机元素
        /// </summary>
        /// <param name="list"></param>
        /// <param name="count"></param>
        /// <typeparam name="T"></typeparam>
        /// <returns></returns>
        public static List<T> GetRandomItemCount<T>(this List<T> list, int count) where T : class
        {
            var result = new List<T>();
            if (list.Count <= count)
                return list;

            var tempList = new List<T>(list);
            for (var i = 0; i < count; i++)
            {
                var index = UnityEngine.Random.Range(0, tempList.Count);
                result.Add(tempList[index]);
                tempList.RemoveAt(index);
            }

            return result;
        }

        /// <summary>
        /// 获取不重复随机元素
        /// </summary>
        /// <param name="array"></param>
        /// <param name="count"></param>
        /// <typeparam name="T"></typeparam>
        /// <returns></returns>
        public static T[] GetRandomItemCount<T>(this T[] array, int count) where T : class
        {
            var result = new T[count];
            if (array.Length <= count)
                return array;

            var tempArray = new T[array.Length];
            Array.Copy(array, tempArray, array.Length);
            for (var i = 0; i < count; i++)
            {
                var index = UnityEngine.Random.Range(0, tempArray.Length);
                result[i] = tempArray[index];
            }

            return result;
        }

        /// <summary>
        /// 移除列表中的重复元素
        /// </summary>
        /// <param name="list"></param>
        /// <typeparam name="T"></typeparam>
        /// <returns></returns>
        public static List<T> RemoveDuplicates<T>(this List<T> list)
        {
            HashSet<T> seen = new HashSet<T>();
            List<T> result = new List<T>();
            foreach (T item in list)
            {
                if (seen.Add(item))
                {
                    result.Add(item);
                }
            }

            return result;
        }

        public static T[] RemoveDuplicates<T>(this T[] array)
        {
            return RemoveDuplicates(array.ToList()).ToArray();
        }

        /// <summary>
        /// 根据权重从列表中随机选择一个元素（整数版本）
        /// </summary>
        /// <typeparam name="T">元素类型</typeparam>
        /// <param name="items">元素列表</param>
        /// <param name="weights">权重列表（整数）</param>
        /// <returns>根据权重随机选择的元素</returns>
        public static T ChooseWithWeights<T>(this IList<T> items, IList<int> weights)
        {
            if (items == null || weights == null)
                throw new ArgumentException("Items and weights cannot be null");

            if (items.Count != weights.Count)
                throw new ArgumentException("Items and weights must have the same length");

            if (items.Count == 0)
                throw new ArgumentException("Items list cannot be empty");

            int totalWeight = 0;
            foreach (int weight in weights)
            {
                if (weight < 0)
                    throw new ArgumentException("Weights must be non-negative");
                totalWeight += weight;
            }

            if (totalWeight <= 0)
                throw new ArgumentException("Total weight must be positive");

            int randomValue = UnityEngine.Random.Range(0, totalWeight);
            int currentWeight = 0;

            for (int i = 0; i < items.Count; i++)
            {
                currentWeight += weights[i];
                if (randomValue < currentWeight)
                {
                    return items[i];
                }
            }

            // 不需要兜底返回，因为使用整数运算不会有精度问题
            return items[^1];
        }

        /// <summary>
        /// 根据权重从列表中随机选择一个元素
        /// </summary>
        /// <typeparam name="T">元素类型</typeparam>
        /// <param name="items">元素列表</param>
        /// <param name="weights">权重列表</param>
        /// <returns>根据权重随机选择的元素</returns>
        public static T ChooseWithWeights<T>(this IList<T> items, IList<float> weights)
        {
            if (items == null || weights == null)
                throw new ArgumentException("Items and weights cannot be null");

            if (items.Count != weights.Count)
                throw new ArgumentException("Items and weights must have the same length");

            if (items.Count == 0)
                throw new ArgumentException("Items list cannot be empty");

            float totalWeight = 0;
            foreach (float weight in weights)
            {
                if (weight < 0)
                    throw new ArgumentException("Weights must be non-negative");
                totalWeight += weight;
            }

            if (totalWeight <= 0)
                throw new ArgumentException("Total weight must be positive");

            float randomValue = UnityEngine.Random.Range(0f, totalWeight);
            float currentWeight = 0;

            for (int i = 0; i < items.Count; i++)
            {
                currentWeight += weights[i];
                if (randomValue <= currentWeight)
                {
                    return items[i];
                }
            }

            // 如果由于浮点数精度问题未返回，则返回最后一个元素
            return items[^1];
        }

        #endregion

        #region Vector相关扩展

        /// <summary>
        /// 将Vector3的x值设置为指定值
        /// </summary>
        public static Vector3 WithX(this Vector3 vector, float x)
        {
            return new Vector3(x, vector.y, vector.z);
        }

        /// <summary>
        /// 将Vector3的y值设置为指定值
        /// </summary>
        public static Vector3 WithY(this Vector3 vector, float y)
        {
            return new Vector3(vector.x, y, vector.z);
        }

        /// <summary>
        /// 将Vector3的z值设置为指定值
        /// </summary>
        public static Vector3 WithZ(this Vector3 vector, float z)
        {
            return new Vector3(vector.x, vector.y, z);
        }

        /// <summary>
        /// 给Vector3添加x值
        /// </summary>
        public static Vector3 AddX(this Vector3 vector, float x)
        {
            return new Vector3(vector.x + x, vector.y, vector.z);
        }

        /// <summary>
        /// 给Vector3添加y值
        /// </summary>
        public static Vector3 AddY(this Vector3 vector, float y)
        {
            return new Vector3(vector.x, vector.y + y, vector.z);
        }

        /// <summary>
        /// 给Vector3添加z值
        /// </summary>
        public static Vector3 AddZ(this Vector3 vector, float z)
        {
            return new Vector3(vector.x, vector.y, vector.z + z);
        }

        /// <summary>
        /// 将Vector2的x值设置为指定值
        /// </summary>
        public static Vector2 WithX(this Vector2 vector, float x)
        {
            return new Vector2(x, vector.y);
        }

        /// <summary>
        /// 将Vector2的y值设置为指定值
        /// </summary>
        public static Vector2 WithY(this Vector2 vector, float y)
        {
            return new Vector2(vector.x, y);
        }

        /// <summary>
        /// 将Vector3的x值设置为指定值
        /// </summary>
        /// <param name="vector"></param>
        /// <param name="x"></param>
        /// <returns></returns>
        public static Vector2 AddX(this Vector2 vector, float x)
        {
            return new Vector2(vector.x + x, vector.y);
        }

        /// <summary>
        /// 将Vector3的y值设置为指定值
        /// </summary>
        /// <param name="vector"></param>
        /// <param name="y"></param>
        /// <returns></returns>
        public static Vector2 AddY(this Vector2 vector, float y)
        {
            return new Vector2(vector.x, vector.y + y);
        }

        #endregion

        #region 数学计算相关

        /// <summary>
        /// 将角度限制在0~360范围内
        /// </summary>
        public static float ClampAngle(float angle)
        {
            while (angle < 0)
                angle += 360;
            while (angle > 360)
                angle -= 360;
            return angle;
        }

        /// <summary>
        /// 将值限制在指定范围内，支持循环
        /// </summary>
        public static float ClampLoop(float value, float min, float max)
        {
            if (value < min)
                return max;
            if (value > max)
                return min;
            return value;
        }

        /// <summary>
        /// 将秒数格式化为时间字符串 (HH:MM:SS)
        /// </summary>
        public static string FormatTime(float seconds)
        {
            TimeSpan time = TimeSpan.FromSeconds(seconds);
            return time.ToString(@"hh\:mm\:ss");
        }

        /// <summary>
        /// 将秒数格式化为时间字符串 (MM:SS)
        /// </summary>
        public static string FormatTimeShort(float seconds)
        {
            TimeSpan time = TimeSpan.FromSeconds(seconds);
            return time.ToString(@"mm\:ss");
        }

        #endregion

        #region 层级和碰撞器相关

        /// <summary>
        /// 设置GameObject及其所有子对象的层级
        /// </summary>
        public static void SetLayerRecursively(this GameObject obj, int layer)
        {
            obj.layer = layer;
            foreach (Transform child in obj.transform)
            {
                SetLayerRecursively(child.gameObject, layer);
            }
        }

        /// <summary>
        /// 检查层掩码是否包含指定层
        /// </summary>
        public static bool ContainsLayer(this LayerMask mask, int layer)
        {
            return mask == (mask | (1 << layer));
        }
        /// <summary>
        /// 获取RectTransform的四个角的世界坐标
        /// </summary>
        public static Vector3[] GetWorldCorners(this RectTransform rectTransform)
        {
            Vector3[] corners = new Vector3[4];
            rectTransform.GetWorldCorners(corners);
            return corners;
        }

        /// <summary>
        /// 检测点是否在Collider范围内
        /// </summary>
        public static bool IsPointInCollider(this Collider collider, Vector3 point)
        {
            return collider.bounds.Contains(point);
        }

        #endregion

        #region GameObject激活相关

        /// <summary>
        /// 设置GameObject是否可见
        /// </summary>
        /// <param name="gameObjects"></param>
        /// <param name="active"></param>
        public static void SetGameObjectsActive(this List<GameObject> gameObjects, bool active)
        {
            gameObjects.ForEach(go => go.SetActive(active));
        }

        public static void SetGameObjectsActive(this GameObject[] gameObjects, bool active)
        {
            foreach (var go in gameObjects)
            {
                if (go != null)
                    go.SetActive(active);
            }
        }

        public static void SetGameObjectsActive<T>(this List<T> gameObjects, bool active) where T : Component
        {
            gameObjects.ForEach(go => go.gameObject.SetActive(active));
        }

        public static void SetGameObjectsActive<T>(this T[] gameObjects, bool active) where T : Component
        {
            foreach (var com in gameObjects)
            {
                if (com != null)
                    com.gameObject.SetActive(active);
            }
        }

        #endregion

        #region 对象拷贝相关

        /// <summary>
        /// 使用序列化/反序列化实现深拷贝
        /// 适用于标记了[Serializable]特性的类
        /// </summary>
        /// <typeparam name="T">要拷贝的类型</typeparam>
        /// <param name="obj">要拷贝的对象</param>
        /// <returns>深拷贝的对象副本</returns>
        public static T DeepCopy<T>(this T obj)
        {
            if (obj == null)
                return default(T);

            // 对于值类型，直接返回
            if (!typeof(T).IsClass)
                return obj;

            try
            {
                using var ms = new MemoryStream();
                var formatter = new BinaryFormatter();
                formatter.Serialize(ms, obj);
                ms.Position = 0;
                return (T)formatter.Deserialize(ms);
            }
            catch (Exception ex)
            {
                Debug.LogError($"Deep copy failed: {ex.Message}");
                return default(T);
            }
        }

        #endregion

        #region UI相关

        /// <summary>
        /// 检查当前鼠标是否点击在UI上
        /// </summary>
        /// <returns>如果鼠标点击在UI上返回true，否则返回false</returns>
        public static bool IsPointerOverUI()
        {
            // 使用EventSystem检测指针是否在UI上
            if (EventSystem.current == null)
                return false;

            // 检查当前是否有指针事件在UI上
            return EventSystem.current.IsPointerOverGameObject();
        }

        /// <summary>
        /// 检查指定位置是否在UI上
        /// </summary>
        /// <param name="screenPosition">屏幕坐标位置</param>
        /// <returns>如果指定位置在UI上返回true，否则返回false</returns>
        public static bool IsPointerOverUI(Vector2 screenPosition)
        {
            // 使用EventSystem检测指针是否在UI上
            if (EventSystem.current == null)
                return false;

            // 创建一个指针事件数据
            PointerEventData eventData = new PointerEventData(EventSystem.current)
            {
                position = screenPosition
            };

            // 射线投射结果列表
            List<RaycastResult> raycastResults = new List<RaycastResult>();
            EventSystem.current.RaycastAll(eventData, raycastResults);

            // 如果有任何射线投射结果，说明点击在UI上
            return raycastResults.Count > 0;
        }

        /// <summary>
        /// 检查当前鼠标是否点击在UI上（基于鼠标当前位置）
        /// </summary>
        /// <returns>如果鼠标点击在UI上返回true，否则返回false</returns>
        public static bool IsMouseOverUI()
        {
            if (EventSystem.current == null)
                return false;

            // 获取当前鼠标位置
            Vector2 mousePosition = Input.mousePosition;
            
            // 创建指针事件数据
            PointerEventData eventData = new PointerEventData(EventSystem.current)
            {
                position = mousePosition
            };

            // 射线投射结果列表
            List<RaycastResult> raycastResults = new List<RaycastResult>();
            EventSystem.current.RaycastAll(eventData, raycastResults);

            // 如果有任何射线投射结果，说明鼠标在UI上
            return raycastResults.Count > 0;
        }
        
        /// <summary>
        /// 设置按钮的标签文本
        /// </summary>
        public static void SetButtonLabel(this Button button, string label)
        {
            if (button == null)
                return;

            var text = button.GetComponentInChildren<Text>();
            if (text != null)
                text.text = label;
        }
        
        /// <summary>
        /// 获取按钮的标签文本
        /// </summary>
        public static string GetButtonLabel(this Button button)
        {
            if (button == null)
                return string.Empty;

            var text = button.GetComponentInChildren<Text>();
            return text != null ? text.text : string.Empty;
        }
        
        /// <summary>
        /// 设置按钮的标签文本
        /// </summary>
        public static void SetButtonTMPLabel(this Button button, string label)
        {
            if (button == null)
                return;

            var text = button.GetComponentInChildren<TextMeshProUGUI>();
            if (text != null)
                text.text = label;
        }
        
        /// <summary>
        /// 获取按钮的TMP标签文本
        /// </summary>
        public static string GetButtonTMPLabel(this Button button)
        {
            if (button == null)
                return string.Empty;

            var text = button.GetComponentInChildren<TextMeshProUGUI>();
            return text != null ? text.text : string.Empty;
        }
        
        /// <summary>
        /// 设置文本组件的内容
        /// </summary>
        public static void SetText(this Text text, string content)
        {
            if (text != null)
                text.text = content;
        }
        
        /// <summary>
        /// 获取文本组件的内容
        /// </summary>
        public static string GetText(this Text text)
        {
            return text != null ? text.text : string.Empty;
        }
        
        /// <summary>
        /// 设置TextMeshProUGUI组件的内容
        /// </summary>
        public static void SetText(this TextMeshProUGUI text, string content)
        {
            if (text != null)
                text.text = content;
        }
        
        /// <summary>
        /// 获取TextMeshProUGUI组件的内容
        /// </summary>
        public static string GetText(this TextMeshProUGUI text)
        {
            return text != null ? text.text : string.Empty;
        }
        
        /// <summary>
        /// 设置输入框的文本内容
        /// </summary>
        public static void SetInputFieldText(this InputField inputField, string text)
        {
            if (inputField != null)
                inputField.text = text;
        }
        
        /// <summary>
        /// 设置TMP输入框的文本内容
        /// </summary>
        public static void SetInputFieldText(this TMP_InputField inputField, string text)
        {
            if (inputField != null)
                inputField.text = text;
        }
        
        /// <summary>
        /// 获取输入框的文本内容
        /// </summary>
        public static string GetInputFieldText(this InputField inputField)
        {
            return inputField != null ? inputField.text : string.Empty;
        }
        
        /// <summary>
        /// 获取TMP输入框的文本内容
        /// </summary>
        public static string GetInputFieldText(this TMP_InputField inputField)
        {
            return inputField != null ? inputField.text : string.Empty;
        }
        
        /// <summary>
        /// 设置滑动条的值
        /// </summary>
        public static void SetSliderValue(this Slider slider, float value)
        {
            if (slider != null)
                slider.value = Mathf.Clamp(value, slider.minValue, slider.maxValue);
        }
        
        /// <summary>
        /// 获取滑动条的值
        /// </summary>
        public static float GetSliderValue(this Slider slider)
        {
            return slider != null ? slider.value : 0f;
        }
        
        /// <summary>
        /// 设置进度条的值
        /// </summary>
        public static void SetScrollbarValue(this Scrollbar scrollbar, float value)
        {
            if (scrollbar != null)
                scrollbar.value = Mathf.Clamp01(value);
        }
        
        /// <summary>
        /// 获取进度条的值
        /// </summary>
        public static float GetScrollbarValue(this Scrollbar scrollbar)
        {
            return scrollbar != null ? scrollbar.value : 0f;
        }
        
        /// <summary>
        /// 设置滚动区域的值
        /// </summary>
        public static void SetScrollRectValue(this ScrollRect scrollRect, Vector2 value)
        {
            if (scrollRect != null)
            {
                scrollRect.horizontalNormalizedPosition = Mathf.Clamp01(value.x);
                scrollRect.verticalNormalizedPosition = Mathf.Clamp01(value.y);
            }
        }
        
        /// <summary>
        /// 获取滚动区域的值
        /// </summary>
        public static Vector2 GetScrollRectValue(this ScrollRect scrollRect)
        {
            if (scrollRect != null)
            {
                return new Vector2(scrollRect.horizontalNormalizedPosition, scrollRect.verticalNormalizedPosition);
            }
            return Vector2.zero;
        }
        
        /// <summary>
        /// 设置下拉框选项
        /// </summary>
        public static void SetDropdownValue(this Dropdown dropdown, int value)
        {
            if (dropdown != null && value >= 0 && value < dropdown.options.Count)
                dropdown.value = value;
        }
        
        /// <summary>
        /// 获取下拉框选项
        /// </summary>
        public static int GetDropdownValue(this Dropdown dropdown)
        {
            return dropdown != null ? dropdown.value : -1;
        }
        
        /// <summary>
        /// 设置TMP下拉框选项
        /// </summary>
        public static void SetDropdownValue(this TMP_Dropdown dropdown, int value)
        {
            if (dropdown != null && value >= 0 && value < dropdown.options.Count)
                dropdown.value = value;
        }
        
        /// <summary>
        /// 获取TMP下拉框选项
        /// </summary>
        public static int GetDropdownValue(this TMP_Dropdown dropdown)
        {
            return dropdown != null ? dropdown.value : -1;
        }
        
        /// <summary>
        /// 设置开关状态
        /// </summary>
        public static void SetToggleIsOn(this Toggle toggle, bool isOn)
        {
            if (toggle != null)
                toggle.isOn = isOn;
        }
        
        /// <summary>
        /// 获取开关状态
        /// </summary>
        public static bool GetToggleIsOn(this Toggle toggle)
        {
            return toggle != null ? toggle.isOn : false;
        }
        
        /// <summary>
        /// 设置图片精灵
        /// </summary>
        public static void SetImageSprite(this Image image, Sprite sprite)
        {
            if (image != null)
                image.sprite = sprite;
        }
        
        /// <summary>
        /// 获取图片精灵
        /// </summary>
        public static Sprite GetImageSprite(this Image image)
        {
            return image != null ? image.sprite : null;
        }
        
        /// <summary>
        /// 设置图片颜色
        /// </summary>
        public static void SetImageColor(this Image image, Color color)
        {
            if (image != null)
                image.color = color;
        }
        
        /// <summary>
        /// 获取图片颜色
        /// </summary>
        public static Color GetImageColor(this Image image)
        {
            return image != null ? image.color : Color.white;
        }
        
        /// <summary>
        /// 设置原始图片颜色
        /// </summary>
        public static void SetRawImageColor(this RawImage rawImage, Color color)
        {
            if (rawImage != null)
                rawImage.color = color;
        }
        
        /// <summary>
        /// 获取原始图片颜色
        /// </summary>
        public static Color GetRawImageColor(this RawImage rawImage)
        {
            return rawImage != null ? rawImage.color : Color.white;
        }
        
        /// <summary>
        /// 设置原始图片纹理
        /// </summary>
        public static void SetRawImageTexture(this RawImage rawImage, Texture texture)
        {
            if (rawImage != null)
                rawImage.texture = texture;
        }
        
        /// <summary>
        /// 获取原始图片纹理
        /// </summary>
        public static Texture GetRawImageTexture(this RawImage rawImage)
        {
            return rawImage != null ? rawImage.texture : null;
        }
        
        /// <summary>
        /// 添加按钮点击监听
        /// </summary>
        public static void AddButtonClickListener(this Button button, UnityEngine.Events.UnityAction call)
        {
            if (button != null && call != null)
                button.onClick.AddListener(call);
        }
        
        /// <summary>
        /// 移除按钮点击监听
        /// </summary>
        public static void RemoveButtonClickListener(this Button button, UnityEngine.Events.UnityAction call)
        {
            if (button != null && call != null)
                button.onClick.RemoveListener(call);
        }
        
        /// <summary>
        /// 添加开关状态改变监听
        /// </summary>
        public static void AddToggleValueChangedListener(this Toggle toggle, UnityEngine.Events.UnityAction<bool> call)
        {
            if (toggle != null && call != null)
                toggle.onValueChanged.AddListener(call);
        }
        
        /// <summary>
        /// 移除开关状态改变监听
        /// </summary>
        public static void RemoveToggleValueChangedListener(this Toggle toggle, UnityEngine.Events.UnityAction<bool> call)
        {
            if (toggle != null && call != null)
                toggle.onValueChanged.RemoveListener(call);
        }
        
        /// <summary>
        /// 添加滑动条值改变监听
        /// </summary>
        public static void AddSliderValueChangedListener(this Slider slider, UnityEngine.Events.UnityAction<float> call)
        {
            if (slider != null && call != null)
                slider.onValueChanged.AddListener(call);
        }
        
        /// <summary>
        /// 移除滑动条值改变监听
        /// </summary>
        public static void RemoveSliderValueChangedListener(this Slider slider, UnityEngine.Events.UnityAction<float> call)
        {
            if (slider != null && call != null)
                slider.onValueChanged.RemoveListener(call);
        }
        
        /// <summary>
        /// 添加输入框值改变监听
        /// </summary>
        public static void AddInputFieldValueChangedListener(this InputField inputField, UnityEngine.Events.UnityAction<string> call)
        {
            if (inputField != null && call != null)
                inputField.onValueChanged.AddListener(call);
        }
        
        /// <summary>
        /// 移除输入框值改变监听
        /// </summary>
        public static void RemoveInputFieldValueChangedListener(this InputField inputField, UnityEngine.Events.UnityAction<string> call)
        {
            if (inputField != null && call != null)
                inputField.onValueChanged.RemoveListener(call);
        }
        
        /// <summary>
        /// 添加TMP输入框值改变监听
        /// </summary>
        public static void AddInputFieldValueChangedListener(this TMP_InputField inputField, UnityEngine.Events.UnityAction<string> call)
        {
            if (inputField != null && call != null)
                inputField.onValueChanged.AddListener(call);
        }
        
        /// <summary>
        /// 移除TMP输入框值改变监听
        /// </summary>
        public static void RemoveInputFieldValueChangedListener(this TMP_InputField inputField, UnityEngine.Events.UnityAction<string> call)
        {
            if (inputField != null && call != null)
                inputField.onValueChanged.RemoveListener(call);
        }
        
        /// <summary>
        /// 添加下拉框选项改变监听
        /// </summary>
        public static void AddDropdownValueChangedListener(this Dropdown dropdown, UnityEngine.Events.UnityAction<int> call)
        {
            if (dropdown != null && call != null)
                dropdown.onValueChanged.AddListener(call);
        }
        
        /// <summary>
        /// 移除下拉框选项改变监听
        /// </summary>
        public static void RemoveDropdownValueChangedListener(this Dropdown dropdown, UnityEngine.Events.UnityAction<int> call)
        {
            if (dropdown != null && call != null)
                dropdown.onValueChanged.RemoveListener(call);
        }
        
        /// <summary>
        /// 添加TMP下拉框选项改变监听
        /// </summary>
        public static void AddDropdownValueChangedListener(this TMP_Dropdown dropdown, UnityEngine.Events.UnityAction<int> call)
        {
            if (dropdown != null && call != null)
                dropdown.onValueChanged.AddListener(call);
        }
        
        /// <summary>
        /// 移除TMP下拉框选项改变监听
        /// </summary>
        public static void RemoveDropdownValueChangedListener(this TMP_Dropdown dropdown, UnityEngine.Events.UnityAction<int> call)
        {
            if (dropdown != null && call != null)
                dropdown.onValueChanged.RemoveListener(call);
        }
        
        /// <summary>
        /// 设置CanvasGroup的透明度
        /// </summary>
        public static void SetCanvasGroupAlpha(this CanvasGroup canvasGroup, float alpha)
        {
            if (canvasGroup != null)
                canvasGroup.alpha = Mathf.Clamp01(alpha);
        }
        
        /// <summary>
        /// 获取CanvasGroup的透明度
        /// </summary>
        public static float GetCanvasGroupAlpha(this CanvasGroup canvasGroup)
        {
            return canvasGroup != null ? canvasGroup.alpha : 0f;
        }
        
        /// <summary>
        /// 设置CanvasGroup的交互性
        /// </summary>
        public static void SetCanvasGroupInteractable(this CanvasGroup canvasGroup, bool interactable)
        {
            if (canvasGroup != null)
                canvasGroup.interactable = interactable;
        }
        
        /// <summary>
        /// 获取CanvasGroup的交互性
        /// </summary>
        public static bool GetCanvasGroupInteractable(this CanvasGroup canvasGroup)
        {
            return canvasGroup != null ? canvasGroup.interactable : false;
        }
        
        /// <summary>
        /// 设置CanvasGroup的射线检测
        /// </summary>
        public static void SetCanvasGroupBlocksRaycasts(this CanvasGroup canvasGroup, bool blocksRaycasts)
        {
            if (canvasGroup != null)
                canvasGroup.blocksRaycasts = blocksRaycasts;
        }
        
        /// <summary>
        /// 获取CanvasGroup的射线检测
        /// </summary>
        public static bool GetCanvasGroupBlocksRaycasts(this CanvasGroup canvasGroup)
        {
            return canvasGroup != null ? canvasGroup.blocksRaycasts : false;
        }
        
        /// <summary>
        /// 设置RectTransform的锚点
        /// </summary>
        public static void SetAnchor(this RectTransform rectTransform, Vector2 anchorMin, Vector2 anchorMax)
        {
            if (rectTransform != null)
            {
                rectTransform.anchorMin = anchorMin;
                rectTransform.anchorMax = anchorMax;
            }
        }
        
        /// <summary>
        /// 获取RectTransform的锚点
        /// </summary>
        public static void GetAnchor(this RectTransform rectTransform, out Vector2 anchorMin, out Vector2 anchorMax)
        {
            if (rectTransform != null)
            {
                anchorMin = rectTransform.anchorMin;
                anchorMax = rectTransform.anchorMax;
            }
            else
            {
                anchorMin = Vector2.zero;
                anchorMax = Vector2.zero;
            }
        }
        
        /// <summary>
        /// 设置RectTransform的锚点和轴心
        /// </summary>
        public static void SetAnchorAndPivot(this RectTransform rectTransform, Vector2 anchor, Vector2 pivot)
        {
            if (rectTransform != null)
            {
                rectTransform.anchorMin = anchor;
                rectTransform.anchorMax = anchor;
                rectTransform.pivot = pivot;
            }
        }
        
        /// <summary>
        /// 设置RectTransform的尺寸
        /// </summary>
        public static void SetSize(this RectTransform rectTransform, Vector2 size)
        {
            if (rectTransform != null)
                rectTransform.sizeDelta = size;
        }
        
        /// <summary>
        /// 获取RectTransform的尺寸
        /// </summary>
        public static Vector2 GetSize(this RectTransform rectTransform)
        {
            return rectTransform != null ? rectTransform.sizeDelta : Vector2.zero;
        }
        
        /// <summary>
        /// 设置RectTransform的宽度
        /// </summary>
        public static void SetWidth(this RectTransform rectTransform, float width)
        {
            if (rectTransform != null)
                rectTransform.sizeDelta = new Vector2(width, rectTransform.sizeDelta.y);
        }
        
        /// <summary>
        /// 获取RectTransform的宽度
        /// </summary>
        public static float GetWidth(this RectTransform rectTransform)
        {
            return rectTransform != null ? rectTransform.sizeDelta.x : 0f;
        }
        
        /// <summary>
        /// 设置RectTransform的高度
        /// </summary>
        public static void SetHeight(this RectTransform rectTransform, float height)
        {
            if (rectTransform != null)
                rectTransform.sizeDelta = new Vector2(rectTransform.sizeDelta.x, height);
        }
        
        /// <summary>
        /// 获取RectTransform的高度
        /// </summary>
        public static float GetHeight(this RectTransform rectTransform)
        {
            return rectTransform != null ? rectTransform.sizeDelta.y : 0f;
        }
        
        /// <summary>
        /// 获取RectTransform的坐标
        /// </summary>
        public static Vector2 GetPosition(this RectTransform rectTransform)
        {
            return rectTransform != null ? (Vector2)rectTransform.position : Vector2.zero;
        }
        
        /// <summary>
        /// 获取RectTransform的局部坐标
        /// </summary>
        public static Vector2 GetLocalPosition(this RectTransform rectTransform)
        {
            return rectTransform != null ? (Vector2)rectTransform.localPosition : Vector2.zero;
        }

        #endregion
    }
}